import logging
from datetime import datetime
from django.conf import settings
from django.http import HttpRequest
from functools import wraps
from common.utils import JsonResponse
from common.const import ResponseStatus
from common.utils import safe_dog
from common.utils.maestro_exceptions import (
    MaestroException,
    VERIFY_CODE_ERROR
)

_LOGGER = logging.getLogger(__name__)


def _wrap2json(data):
    assert isinstance(data, dict) or isinstance(data, list)
    return JsonResponse(dict(status=ResponseStatus.OK.value, msg='', data=data), status=200)


def response_wrapper(func):
    def _wrapper(request, *args, **kwargs):
        if settings.DEBUG:
            return _wrap2json(func(request, *args, **kwargs))
        try:
            return _wrap2json(func(request, *args, **kwargs))
        except MaestroException as e:
            _LOGGER.info('server error! %s %s %s', 500, e or e.detail_message, request.path)
            return JsonResponse(dict(status=ResponseStatus.FAIL.value, msg=str(e) or e.detail_message,
                                     timestamp=datetime.now()), status=500)
        except:
            user_repr = "%s (%s)" % (
                getattr(request.user, 'id', ""), getattr(request.user, 'user_name', "")) if getattr(request, 'user',
                                                                                                    False) else ''
            _LOGGER.exception('REQUEST URL: %s, USER: %s' % (request.path, user_repr))
            return JsonResponse(dict(status=ResponseStatus.FAIL.value, msg='服务异常',
                                     timestamp=datetime.now()), status=500)
    return _wrapper


def validate_form(form_class):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            request = args[0]
            if not isinstance(request, HttpRequest):
                raise Exception("view的第一个参数必须是request,如果用于class-based view, "
                                "请使用@method_decorator(require_login)")
            form = form_class(request.DATA)
            if not form.is_valid():
                return JsonResponse(dict(status=ResponseStatus.FAIL.value, msg='传参错误'), status=500)
            return func(*args, **kwargs, cleaned_data=form.cleaned_data)
        return wrapper
    return decorator


def get_request_ip(request):
    if 'HTTP_X_FORWARDED_FOR' in request.META.keys():
        ip = request.META['HTTP_X_FORWARDED_FOR']
    else:
        ip = request.META['REMOTE_ADDR']

    return ip


def check_user_vcode(request, user_id=None, ip=None):
    if settings.IS_PRODUCTION_ENV:
        user_id = int(user_id) if user_id else int(request.user_id)
        ip = ip or get_request_ip(request)
        verify_code = request.META.get('HTTP_X_AUTH_VCODE')
        if not verify_code:
            raise MaestroException(VERIFY_CODE_ERROR)
        if not safe_dog.client.verify_token(user_id, verify_code, ip):
            raise MaestroException(VERIFY_CODE_ERROR)
